﻿using Newtonsoft.Json;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using NPOI.XWPF.UserModel;
using Org.BouncyCastle.Crypto;
using PluSoft.Utils;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Services.Protocols;
using System.Web.UI.WebControls;
using YunShop_WebAPI.Model;
using static YunShop_WebAPI.Model.VdianItemListGetResp;
using static YunShop_WebAPI.Model.WeiDianAccessTokenResp;
using static YunShop_WebAPI.Model.WeiDianPushOrderModel.Message;

namespace YunShop_WebAPI.BLL
{
    public class WeiDianService
    {
        public static string APPKEY = "3703032898";
        public static string Secret = "6589d548b657ccaf8857e73011530027";
        public static string REDIRECT_URI = "https://erp6.pos08.com/weidian/callback";
        public static int TokenType = 1;//t_Accesstoken.Type = 1

        /// <summary>
        ///  获取授权 URL 
        /// </summary>
        /// <returns></returns>
        public static string GenWeiDianAuthUrl(string m_STATE)
        {
            //string m_STATE = "333";  // 自定义的state
            return $"https://oauth.open.weidian.com/oauth2/authorize?appkey={APPKEY}&redirect_uri={REDIRECT_URI}&response_type=code&state={m_STATE}";
        }

        /// <summary>
        ///  获取授权 URL 
        /// </summary>
        /// <returns></returns>
        public static bool SaveWeiDianAuthUrl(string code, int userId)
        {
            string sql = @"if Not exists(Select * from t_Accesstoken where FUserID = @FUserID and FType = @FType)
                begin
	                Insert into t_Accesstoken(FCorpID, FHostID, FCode, FAccessToken, FRefershToken, FRefershTime, FType,FUserID,FStockID)
                    SELECT a.FCorpID, b.FHostID,@FCode as FCode,'' as FAccessToken, '' as FRefershToken,
                    GETDATE()-2 as FRefershTime, @FType as FType,a.FItemID as FUserID, b.FStockID
                    FROM dbo.t_User AS a INNER JOIN dbo.t_Corpration AS b ON a.FCorpID = b.FItemID	                
                    Where a.FItemID = @FUserID
                end else begin
	                Update t_Accesstoken set FCode = @FCode where FUserID = @FUserID and FType = @FType
                end Select FCode from t_Accesstoken where FCode = @FCode and FType = @FType";
            SqlParameterList par_list = new SqlParameterList();
            par_list.Add("@FUserID", SqlDbType.Int, userId);
            par_list.Add("@FCode", SqlDbType.VarChar, code);
            par_list.Add("@FType", SqlDbType.Int, TokenType);
            DataTable dt = DBHelper.GetDataTable(sql, par_list.Get_List(), DBHelper.ConnMaster);
            if (dt == null || dt.Rows.Count == 0) return false;
            return true;
        }

        public static void SaveAccesstoken(WeiDianAccessTokenResp res, string code)
        {
            try
            {
                string sql = @"Update t_Accesstoken set FAccessToken = @FAccessToken,FRefershToken = @FRefershToken,
                        FRefershTime = Getdate(),shop_id = @shop_id where FCode = @FCode and FType = @FType
                        Select FCode from t_Accesstoken where FCode = @FCode and FType = @FType";
                SqlParameterList par_list = new SqlParameterList();
                par_list.Add("@FAccessToken", SqlDbType.VarChar, res.result.access_token);
                par_list.Add("@FRefershToken", SqlDbType.VarChar, res.result.refresh_token);
                par_list.Add("@shop_id", SqlDbType.BigInt, CommonFun.ConvertToBigInt(res.result.openid));
                par_list.Add("@FCode", SqlDbType.VarChar, code);
                par_list.Add("@FType", SqlDbType.Int, TokenType);
                DataTable dt = DBHelper.GetDataTable(sql, par_list.Get_List(), DBHelper.ConnMaster);
            }
            catch { }
        }

        /// <summary>
        /// 获取Access Token
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static async Task<WeiDianAccessTokenResp> GetWeiDianAccessToken(string code)
        {
            string url = $"https://oauth.open.weidian.com/oauth2/access_token?appkey={APPKEY}&secret={Secret}&code={code}&grant_type=authorization_code";
            WeiDianAccessTokenResp res = null;
            using (HttpClient httpClient = new HttpClient())
            {
                try
                {
                    HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(new { }));
                    httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
                    httpContent.Headers.ContentType.CharSet = "utf-8";
                    HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
                    response.EnsureSuccessStatusCode();
                    string result = await response.Content.ReadAsStringAsync();
                    SystemInfo.WriteInterfaceLog("GetWeiDianAccessToken", result, "1WD", "3A", DBHelper.ConnMaster);
                    res = JsonConvert.DeserializeObject<WeiDianAccessTokenResp>(result);
                    SaveAccesstoken(res, code);
                }
                catch (HttpRequestException ex)
                {
                    SystemInfo.WriteInterfaceLog("GetWeiDianAccessToken", ex.Message, "1WD", "1A", DBHelper.ConnMaster);

                    Console.WriteLine(ex.Message);
                }
            }
            return res;

        }

        /// <summary>
        /// 获取Access Token
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static async Task<string> RefreshWeiDianTokenAll()
        {
            string msg = "操作成功!";
            string m_sql = $"SELECT * FROM t_Accesstoken where DATEDIFF(hour, FRefershTime, GetDate()) > 10";
            ArrayList datalist = DBHelper.Select(m_sql, DBHelper.ConnMaster);
            if (datalist == null || datalist.Count == 0) return "没有可刷新的令牌";
            foreach (Hashtable item in datalist)
            {
                string m_refreshToken = CommonFun.ConvertToString(item["FRefershToken"]);
                string code = CommonFun.ConvertToString(item["FCode"]);
                WeiDianAccessTokenResp resp = await WeiDianService.RefreshWeiDianTokenAsync(m_refreshToken);
                SaveAccesstoken(resp, code);
            }
            msg = string.Format("共刷新令牌【{0}】条", datalist.Count.ToString());
            return msg;
        }

        public static async Task<WeiDianAccessTokenResp> RefreshWeiDianTokenAsync(string refresh_token)
        {
            string url = $"https://oauth.open.weidian.com/oauth2/refresh_token?appkey={APPKEY}&grant_type=refresh_token&refresh_token={refresh_token}";
            WeiDianAccessTokenResp res = null;
            using (HttpClient httpClient = new HttpClient())
            {
                try
                {
                    HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(new { }));
                    httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json")
                    {
                        CharSet = "utf-8"
                    };
                    HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
                    response.EnsureSuccessStatusCode();
                    string dt = await response.Content.ReadAsStringAsync();
                    res = JsonConvert.DeserializeObject<WeiDianAccessTokenResp>(dt);
                }
                catch (HttpRequestException ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            return res;
        }

        /// <summary>
        /// 同步所有的商品到微店平台
        /// </summary>
        /// <param name="mCorpID"></param>
        /// <returns></returns>
        public static async Task<bool> SyncGoodsToWeiDian(int mCorpID)
        {
            try
            {
                string conn = SystemInfo.GetClusterConn(mCorpID);
                ArrayList datalist = GetGoodsInterface(mCorpID, conn);
                if (datalist == null || datalist.Count == 0) { return false; }

                string m_Token = GetAccesstoken(mCorpID);
                //string m_Token = "d808dcb7cc42086851adb50517bae02c9fbe1b3673";
                foreach (Hashtable item in datalist)
                {
                    long goodsId = CommonFun.ConvertToBigInt(item["identifier"]);
                    long fModifyTime = CommonFun.ConvertToBigInt(item["FModifyTime"]);
                    long itemId = CommonFun.ConvertToBigInt(item["itemId"]);
                    if (CommonFun.ConvertToBigInt(item["FSyncTimes"]) == 0)
                    {
                        //添加单个商品
                        VdianItemAddResp data = await WeiDianService.VdianItemAdd(item, m_Token);
                        if ((data != null) && (data.status.status_code == 0))
                        {
                            SaveGoodsInterface(goodsId, data.result.itemId, fModifyTime, conn);
                        }
                    }
                    else if (CommonFun.ConvertToBigInt(item["FDeleted"]) != 1)
                    {
                        //删除单个商品
                        var data = await WeiDianService.VdianItemDelete(itemId.ToString(), m_Token);
                        if ((data != null) && (data.status.status_code == 0))
                        {
                            SaveGoodsInterface(goodsId, itemId, fModifyTime, conn);
                        }
                    }
                    else
                    {
                        //更新单个商品
                        var data = await WeiDianService.VdianItemUpdate(item, m_Token);
                        if ((data != null) && (data.status.status_code == 0))
                        {
                            SaveGoodsInterface(goodsId, itemId, fModifyTime, conn);
                        }
                    }
                }
            }
            catch { }
            return true;
        }

        /// <summary>
        ///  获取授权 URL 
        /// </summary>
        /// <returns></returns>
        public static int SavePushOrderJson(string connstr,string order_json, string order_id)
        {
            string sql = "";
            if (order_json == "success")
            {
                sql = "Update t_InterfaceZoop set success = 1 where order_id = @order_id";
            }
            else
            {
                sql = @"if Not exists(Select * from t_InterfaceZoop where order_id = @order_id)
                    begin
	                    Insert into t_InterfaceZoop(order_id, order_js, date_time, success)
	                    values(@order_id, @order_js, Getdate(), 0)
                    end";
            }

            SqlParameterList par_list = new SqlParameterList();
            par_list.Add("@order_id", SqlDbType.VarChar, order_id);
            par_list.Add("@order_js", SqlDbType.Text, 0, order_json);
            DBHelper.ExeSQL(sql, par_list.Get_List(), connstr);

            sql = @"Select entry_id from t_InterfaceZoop where order_id = @order_id";
            SqlParameterList par_list1 = new SqlParameterList();
            par_list1.Add("@order_id", SqlDbType.VarChar, order_id);
            DataTable dt = DBHelper.GetDataTable(sql, par_list1.Get_List(), connstr);
            if (dt == null || dt.Rows.Count == 0) return 0;
            return CommonFun.ConvertToInt(dt.Rows[0]["entry_id"]);
        }

        /// <summary>
        /// 同步订单到商云
        /// </summary>
        /// <param name="mCorpID"></param>
        /// <returns></returns>
        //public static Task<string> PushOrder(string json)
        public static Task<string> PushOrder(string json)
        {
            try
            {
                var model = JsonConvert.DeserializeObject<WeiDianPushOrderModel>(json);
                if (!model.type.Equals("weidian.order.finished")) return Task.FromResult("success");                
                string sql = $"SELECT * From t_Accesstoken WHERE shop_id = {model.shopId} and FType = {TokenType}";
                ArrayList datalist = DBHelper.Select(sql, DBHelper.ConnMaster);
                if (datalist == null || datalist.Count == 0)
                {
                    SystemInfo.WriteInterfaceLog("PushOrder", string.Format("无法获取门店权限t_Accesstoken表。model.shopId={0}", model.shopId), "1WD", "1A", DBHelper.ConnMaster);
                    return Task.FromResult("false");
                }
                Hashtable ht_corp = datalist[0] as Hashtable;
                int mCorpID = CommonFun.ConvertToInt(ht_corp["FCorpID"]);
                int mUserID = CommonFun.ConvertToInt(ht_corp["FUserID"]);
                int mStockID = CommonFun.ConvertToInt(ht_corp["FStockID"]);
                if ((mCorpID == 0) || (mUserID == 0) || (mStockID == 0))
                {
                    SystemInfo.WriteInterfaceLog("PushOrder", "t_Accesstoken授权门店信息不完整。", "1WD", "1A", DBHelper.ConnMaster);
                    return Task.FromResult("false");
                }
                string connstr = SystemInfo.GetClusterConn(mCorpID);
                long KInterID = SavePushOrderJson(connstr,json, model.message.order_id);
                sql = @"Exec sp_API_GetPosClass @hCorpID,@hStockID,@hUserID";
                SqlParameterList par_list = new SqlParameterList();
                par_list.Add("@hCorpID", SqlDbType.Int, mCorpID);
                par_list.Add("@hStockID", SqlDbType.Int, mStockID);
                par_list.Add("@hUserID", SqlDbType.BigInt, mUserID);
                DataTable dt_class = DBHelper.GetDataTable(sql, par_list.Get_List(), connstr);
                if ((dt_class == null) || (dt_class.Rows.Count == 0))
                {
                    SystemInfo.WriteInterfaceLog("PushOrder", "无法获取sp_API_GetPosClass。", "1WD", "1A", DBHelper.ConnMaster);
                    return Task.FromResult("false");
                }

                sql = @"SELECT Convert(bigint,0) KInterID, Convert(varchar(50),0) AS FBillNo, GETDATE() AS FDate, Convert(bigint,0) AS FClassID, 
                    Convert(bigint,0) AS FUserID,Convert(bigint,0) FCorpID, Convert(bigint,0) AS FStockID, Convert(bigint,0) AS FMemberID, 
                    Convert(decimal(14,2),0) FQty,Convert(decimal(14,2),0) AS FAmount,Convert(decimal(14,2),0) AS FRealAmount,
                    Convert(decimal(14,2),0) as FPoint,Convert(bigint,0) as FEmpID,Convert(decimal(14,2),0) as FDepositAmt,0 as FDepositFlag,
                    0 as FHostID,Convert(varchar(50),0) as FMemberNumber, Convert(varchar(50),0) as mSystemAppID,Convert(varchar(50),0) as mSystemSign,
                    Convert(bigint,0) as FTimeStamp,0 as FMallShopID,Convert(decimal(14,2),0) as FPurAmount";

                DataTable dt_1 = DBHelper.GetDataTable(sql, connstr);

                string sql_detail = @"SELECT CONVERT(bigint, 0) AS MInterID, g.FItemID AS FGoodsID, CONVERT(decimal(14, 2), 0) AS mFQty, 
                    CONVERT(decimal(14,2), 0) AS mFPrice, CONVERT(decimal(14, 2), 0) AS mFActualPrice, CONVERT(decimal(14, 2), 0) AS mFAmount, 
                    CONVERT(decimal(14, 2), 0) AS mFActualAmount, 1 AS mFDataType, g.FConvert AS mFConvert, 
                    g.FSubItemID AS mFSubItemID, CONVERT(bigint, 0) AS mFEmpID, CONVERT(varchar(50), 0) AS mFRemark, 
                    CONVERT(bigint, 0) AS MEntryID, 0 AS FPackFlag, CONVERT(decimal(14, 2), 0) AS FPurPrice, 
                    CONVERT(decimal(14, 2), 0) AS FPurAmount FROM dbo.t_GoodsInterface AS a INNER JOIN
                    dbo.t_Goods AS g ON a.FItemID = g.FItemID WHERE (a.FMallGoodsID = {0})";
                DataTable dt_2 = DBHelper.GetDataTable(string.Format(sql_detail, -99), connstr);                

                sql = @"SELECT Top 1 Convert(bigint,0) MInterID, 4 AS FPayID, Convert(decimal(14,2),0) AS mFAmount, Convert(decimal(14,2),0) AS mFPayAmount,
                    0 as FMemberDepositID,0 as FCouSendID,0 as mFConvertPoint,Convert(varchar(50),0) as mFBillOrderNo";
                DataTable dt_3 = DBHelper.GetDataTable(sql, connstr);

                DataSet ds = new DataSet();

                string mSystemSign = SystemInfo.SetSystemAppID(mUserID, mCorpID, mStockID);
                DataTable dt1 = dt_1.Copy();
                dt1.TableName = "Table1";
                dt1.Rows[0].BeginEdit();
                dt1.Rows[0]["KInterID"] = KInterID;
                dt1.Rows[0]["FBillNo"] = model.message.order_id;
                dt1.Rows[0]["FClassID"] = dt_class.Rows[0]["KInterID"];
                dt1.Rows[0]["FUserID"] = mUserID;
                dt1.Rows[0]["FCorpID"] = mCorpID;
                dt1.Rows[0]["FStockID"] = mStockID;
                dt1.Rows[0]["mSystemSign"] = mSystemSign;

                decimal mTotalQty = 0;
                decimal mTotalAmt = 0;

                DataTable dt2 = dt_2.Copy();
                dt2.Rows.Clear();
                dt2.TableName = "Table2";
                foreach (var item in model.message.items)
                {
                    DataTable dt_goods = DBHelper.GetDataTable(string.Format(sql_detail, item.item_id), connstr);
                    if ((dt_goods == null) || (dt_goods.Rows.Count == 0))
                    {
                        SystemInfo.WriteInterfaceLog("PushOrder", string.Format("无法获取商品【{0}】对照表。", item.item_name), "1WD", "1A", DBHelper.ConnMaster);
                        return Task.FromResult("false");
                    }

                    DataRow originalRow = dt_goods.Rows[0];
                    DataRow newRow = dt2.NewRow();
                    foreach (DataColumn column in dt_goods.Columns)
                    {
                        newRow[column.ColumnName] = originalRow[column.ColumnName];
                    }
                    newRow["MInterID"] = model.message.order_id;
                    newRow["mFQty"] = item.quantity;
                    newRow["mFPrice"] = item.price;
                    newRow["mFActualPrice"] = item.price;
                    newRow["mFAmount"] = item.quantity * item.price;
                    newRow["mFActualAmount"] = item.quantity * item.price;
                    dt2.Rows.Add(newRow);

                    mTotalQty += item.quantity ;
                    mTotalAmt += item.quantity * item.price;
                }

                dt1.Rows[0]["FQty"] = mTotalQty;
                dt1.Rows[0]["FAmount"] = mTotalAmt;
                dt1.Rows[0]["FRealAmount"] = mTotalAmt;
                dt1.Rows[0].EndEdit();

                DataTable dt3 = dt_3.Copy();
                dt3.TableName = "Table3";
                dt3.Rows[0].BeginEdit();
                dt3.Rows[0]["MInterID"] = model.message.order_id;
                dt3.Rows[0]["mFAmount"] = mTotalAmt;
                dt3.Rows[0]["mFPayAmount"] = mTotalAmt;
                dt3.Rows[0].EndEdit();

                ds.Tables.Add(dt1);
                ds.Tables.Add(dt2);
                ds.Tables.Add(dt3);

                if (ds.Tables[0].Rows.Count == 0) return Task.FromResult("false");

                YunWebService.POSWebServiceEx proxy = new YunWebService.POSWebServiceEx();
                //proxy.Url = "http://localhost:13065/Interfaces/POSWebServiceEx.asmx";
                int iReturnID = proxy.SetPOSBillData(UnZipClass.ConvertDataSetToZipBuffer(ds), mSystemSign);
                if (iReturnID > 0)
                {
                    SavePushOrderJson(connstr, "success", model.message.order_id);
                    return Task.FromResult("success");
                }
            }
            catch (Exception ex){
                SystemInfo.WriteInterfaceLog("PushOrder", $"Exception={ex.Message}", "1", "1A", DBHelper.ConnMaster);
            }
            return Task.FromResult("false");
        }


        /// <summary>
        /// 获取所有未同步的商品列表
        /// </summary>
        /// <param name="mCorpID"></param>
        /// <returns></returns>
        public static ArrayList GetGoodsInterface(int mCorpID, string conn)
        {
            try
            {

                string sql = @"SELECT a.FCode AS barcode, a.FPurPrice AS costPrice, a.FItemID AS identifier,
                    a.FName AS itemName, a.FPosPrice AS price, 1 AS status, 99 AS stock,a.FModifyTime,
                    b.FSyncTimes,b.FMallGoodsID as itemId,a.FDeleted
                    FROM dbo.t_Goods AS a LEFT OUTER JOIN
                    dbo.t_GoodsInterface AS b ON a.FItemID = b.FItemID
                    where a.FCorpID = @FCorpID and (a.FModifyTime > b.FSyncTimes or b.FSyncTimes is null)";
                SqlParameterList par_list = new SqlParameterList();
                par_list.Add("@FCorpID", SqlDbType.Int, mCorpID);
                ArrayList list = DBHelper.Select(sql, par_list.Get_List(), conn);
                return list;
            }
            catch { }
            return null;
        }

        /// <summary>
        /// 保存已同步的商品信息
        /// </summary>
        /// <param name="mCorpID"></param>
        /// <returns></returns>
        public static void SaveGoodsInterface(long mGoodsID, long sMallGoodsID, long mModifyTime, string conn)
        {
            try
            {
                string sql = @"if exists(Select * from t_GoodsInterface where FItemID = @FItemID)
                    begin
	                    Update t_GoodsInterface set FSyncTimes = @FSyncTimes where FItemID = @FItemID
                    end else begin
	                    Insert into t_GoodsInterface(FItemID,FMallGoodsID,FSyncTimes)
	                    Values(@FItemID,@FMallGoodsID,@FSyncTimes)
                    end Select @FItemID as FItemID";
                SqlParameterList par_list = new SqlParameterList();
                par_list.Add("@FItemID", SqlDbType.BigInt, mGoodsID);
                par_list.Add("@FMallGoodsID", SqlDbType.BigInt, sMallGoodsID);
                par_list.Add("@FSyncTimes", SqlDbType.BigInt, mModifyTime);
                ArrayList list = DBHelper.Select(sql, par_list.Get_List(), conn);
            }
            catch { }
        }

        /// <summary>
        /// 获取存在数据库的Token
        /// </summary>
        /// <param name="m_corpId"></param>
        /// <returns></returns>
        public static string GetAccesstoken(int m_corpId)
        {
            string m_sql = $"SELECT * From t_Accesstoken WHERE FCorpID = {m_corpId}";
            ArrayList datalist = DBHelper.Select(m_sql, DBHelper.ConnMaster);
            if (datalist == null || datalist.Count == 0) return "";
            Hashtable ht_result = datalist[0] as Hashtable;
            return CommonFun.ConvertToString(ht_result["FAccessToken"]);
        }

        public static async Task<VdianItemBatchAddResp> VdianItemBatchAdd(int m_corpId)
        {
            string m_sql = $"SELECT top 1 a.FCode AS barcode, a.FPurPrice AS costPrice, a.FItemID AS identifier," +
                $" a.FName AS itemName, a.FPosPrice AS price, 1 AS status, 99 AS stock, b.FProImage as imgs " +
                $"FROM   dbo.t_Goods AS a INNER JOIN dbo.t_GoodsDetail AS b ON a.FItemID = b.FItemID " +
                $"WHERE a.FCorpID = {m_corpId}";
            ArrayList datalist = DBHelper.Select(m_sql, DBHelper.ConnMaster);

            if (datalist != null && datalist.Count > 0)
            {
                foreach (var item in datalist)
                {
                    Hashtable ht_result = item as Hashtable;
                    ArrayList list_img = new ArrayList();
                    Hashtable ht_img = new Hashtable();
                    ht_img["url"] = "https://si.geilicdn.com/open1750183349-1750183349-015900000193f63392c40a22d234-unadjust_344_287.png";
                    ht_img["title"] = ht_result["itemName"];
                    list_img.Add(ht_img);

                    ht_result["imgs"] = list_img;
                    ht_result["identifier"] = CommonFun.ConvertToString(ht_result["identifier"]);
                    ht_result["costPrice"] = CommonFun.ConvertToString(ht_result["costPrice"]);
                    ht_result["price"] = CommonFun.ConvertToString(ht_result["price"]);
                }
            }

            string accessToken = GetAccesstoken(m_corpId);
            if (string.IsNullOrEmpty(accessToken))
            {
                SystemInfo.writeServiceLog("VdianItemBatchAdd", "accessToken为空，提交失败", "1WD", "1A", DBHelper.ConnMaster);
                return null;
            }
            var itemsJson = JsonConvert.SerializeObject(new
            {
                items = datalist
            });

            var publicDict = new Dictionary<string, object>
            {
                { "method", "vdian.item.batch.add" },
                { "access_token", accessToken },
                { "version", "1.0" },
                { "format", "json" }
            };
            var publicJson = JsonConvert.SerializeObject(publicDict);

            var itemsEscaped = Uri.EscapeDataString(itemsJson);
            var publicEscaped = Uri.EscapeDataString(publicJson);

            var url = $"https://api.vdian.com/api?param={itemsEscaped}&public={publicEscaped}";
            VdianItemBatchAddResp res = null;
            using (HttpClient httpClient = new HttpClient())
            {
                try
                {
                    HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(new { }));
                    httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json")
                    {
                        CharSet = "utf-8"
                    };
                    HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
                    response.EnsureSuccessStatusCode();
                    string dt = await response.Content.ReadAsStringAsync();
                    res = JsonConvert.DeserializeObject<VdianItemBatchAddResp>(dt);
                }
                catch (HttpRequestException ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            return res;
        }

        /// <summary>
        /// 6 .获取店铺商品
        /// </summary>
        /// <returns></returns>
        public static async Task<VdianItemListGetResp> VdianItemListGet(string m_Token, string m_pageNum, string m_pageSize)
        {
            return await WeiDianRPC<VdianItemListGetResp>(m_Token, new
            {
                page_num = m_pageNum,
                page_size = m_pageSize,
                status = 1
            }, "vdian.item.list.get");
        }

        public static async Task<VdianItemDeleteResp> VdianItemBatchDelete(string m_Token, string ids)
        {

            return await WeiDianRPC<VdianItemDeleteResp>(m_Token, new
            {
                itemids = ids
            }, "vdian.item.batchDelete");
        }


        #region 微店RPC封装
        public static async Task<T> WeiDianRPC<T>(string token, dynamic param, string method, string version = "1.0")
        {

            var itemsJson = JsonConvert.SerializeObject(param);

            var publicDict = new Dictionary<string, object>
            {
                { "method", method },
                { "access_token", token },
                { "version", version },
            };
            var publicJson = JsonConvert.SerializeObject(publicDict);

            var itemsEscaped = Uri.EscapeDataString(itemsJson);
            var publicEscaped = Uri.EscapeDataString(publicJson);

            var url = $"https://api.vdian.com/api?param={itemsEscaped}&public={publicEscaped}";
            T res;
            using (HttpClient httpClient = new HttpClient())
            {
                try
                {
                    HttpContent httpContent = new StringContent(JsonConvert.SerializeObject(new { }));
                    httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json")
                    {
                        CharSet = "utf-8"
                    };
                    HttpResponseMessage response = await httpClient.PostAsync(url, httpContent);
                    response.EnsureSuccessStatusCode();
                    string dt = await response.Content.ReadAsStringAsync();
                    res = JsonConvert.DeserializeObject<T>(dt);
                    return res;
                }
                catch (HttpRequestException ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            return default;
        }
        #endregion

        /// <summary>
        /// 8. 添加单个商品
        /// </summary>
        /// <returns></returns>
        public static async Task<VdianItemAddResp> VdianItemAdd(Hashtable ht_goods, string token)
        {
            ArrayList list_img = new ArrayList();
            Hashtable ht_img = new Hashtable();
            ht_img["url"] = "https://si.geilicdn.com/open1750183349-1750183349-015900000193f63392c40a22d234-unadjust_344_287.png";
            ht_img["title"] = ht_goods["itemName"];
            list_img.Add(ht_img);

            ht_goods["imgs"] = list_img;
            ht_goods["identifier"] = CommonFun.ConvertToString(ht_goods["identifier"]);
            ht_goods["costPrice"] = CommonFun.ConvertToDecimal(ht_goods["costPrice"]) > 0 ? CommonFun.ConvertToString(ht_goods["costPrice"]) : "0.01";
            ht_goods["price"] = CommonFun.ConvertToString(ht_goods["price"]);

            return await WeiDianRPC<VdianItemAddResp>(token, ht_goods, "vdian.item.add", "1.5");
        }

        /// <summary>
        /// 9.删除单个商品
        /// </summary>
        /// <returns></returns>
        public static async Task<VdianItemDeleteResp> VdianItemDelete(string id, string m_Token)
        {
            return await WeiDianRPC<VdianItemDeleteResp>(m_Token, new
            {
                itemid = id
            }, "vdian.item.delete");
        }

        /// <summary>
        /// 10.更新单个商品
        /// </summary>
        /// <returns></returns>
        public static async Task<VdianItemUpdateResp> VdianItemUpdate(Hashtable ht, string m_Token)
        {
            try
            {
                //先获取再更新，要读imgs
                VdianItemInfoGetResp data = await WeiDianRPC<VdianItemInfoGetResp>(m_Token, ht, "vdian.item.get", "1.1");
                if ((data != null) && (data.status.status_code == 0))
                {
                    var imgs = data.result.imgs;
                    if ((imgs == null) || (imgs.Count == 0)) return null;
                    ArrayList list_img = new ArrayList();
                    Hashtable ht_img = new Hashtable();
                    ht_img["url"] = imgs[0];
                    ht_img["title"] = ht["itemName"];
                    list_img.Add(ht_img);

                    ArrayList deliveryList = new ArrayList();
                    Hashtable ht_del = new Hashtable();
                    ht_del["delivery_id"] = 4;
                    ht_del["delivery_name"] = "快递发货";
                    deliveryList.Add(ht_del);

                    Hashtable ht_update = new Hashtable();
                    ht_update["itemid"] = CommonFun.ConvertToString(ht["itemId"]);
                    ht_update["item_delivery_list"] = deliveryList;
                    ht_update["imgs"] = list_img;
                    ht_update["item_name"] = CommonFun.ConvertToString(ht["itemName"]);
                    ht_update["price"] = CommonFun.ConvertToString(ht["price"]);
                    ht_update["cost_price"] = CommonFun.ConvertToString(ht["cost_price"]);
                    ht_update["status"] = CommonFun.ConvertToInt(ht["status"]);
                    ht_update["barcode"] = CommonFun.ConvertToString(ht["barcode"]);
                    ht_update["no_barcode_item"] = "1";
                    WeiDianUpdateDto weiDianUpdateDto = new WeiDianUpdateDto()
                    {
                        itemid = CommonFun.ConvertToString(ht["itemId"]),
                        item_delivery_list = new List<int>()
                        {
                            /*   new WeiDianUpdateDto.Delivery(){4
                                 *//*   delivery_id=4,
                                   delivery_name="快递发货"
                                    }*//*
                                   },*/
                        4
                        },
                        barcode = CommonFun.ConvertToString(ht["barcode"]),
                        cost_price = CommonFun.ConvertToDecimal(ht["cost_price"]) > 0 ? CommonFun.ConvertToString(ht["cost_price"]) : "0.01",
                        imgs = new List<WeiDianUpdateDto.Imgs>() {
                         new WeiDianUpdateDto.Imgs(){
                          url=imgs[0], title=CommonFun.ConvertToString(ht["itemName"])}
                         },
                        item_name = CommonFun.ConvertToString(ht["itemName"]),
                        price = CommonFun.ConvertToString(ht["price"]),
                        status = CommonFun.ConvertToInt(ht["status"])
                    };
                    VdianItemUpdateResp resut = await WeiDianRPC<VdianItemUpdateResp>(m_Token, weiDianUpdateDto, "vdian.item.update", "1.5");
                    return resut;
                }
            }
            catch (Exception e) { }
            return null;
        }
    }
}
